#include <stdio.h>
#include <string.h>
void file_r(FILE *fp)
{
    fp = fopen("./file1.txt", "r");
    if (fp == NULL)
    {
        printf("打开文件失败!\n");
        return;
    }
    else
    {
        printf("打开文件成功!\n");
    }
    fclose(fp);
}
void file_w(FILE *fp)
{
    fp = fopen("./file1.txt", "w");
    if (fp == NULL)
    {
        printf("打开文件失败!\n");
        return;
    }
    else
    {
        printf("打开文件成功!\n");
    }
    fclose(fp);
}
void file_a(FILE *fp)
{
    fp = fopen("./file1.txt", "a");
    if (fp == NULL)
    {
        printf("打开文件失败!\n");
        return;
    }
    else
    {
        printf("打开文件成功!\n");
    }
    fclose(fp);
}
void file_w_add(FILE *fp)
{
    fp = fopen("./file1.txt", "w+");
    if (fp == NULL)
    {
        printf("打开文件失败!\n");
        return;
    }
    else
    {
        printf("打开文件成功!\n");
    }
    fclose(fp);
}
void file_r_add(FILE *fp)
{
    fp = fopen("./file1.txt", "r+");
    if (fp == NULL)
    {
        printf("打开文件失败!\n");
        return;
    }
    else
    {
        printf("打开文件成功!\n");
    }
    fclose(fp);
}

void file_a_add(FILE *fp)
{
    fp = fopen("./file1.txt", "a+");
    if (fp == NULL)
    {
        printf("打开文件失败!\n");
        return;
    }
    else
    {
        printf("打开文件成功!\n");
    }
    fclose(fp);
}
void file_position()
{
    FILE *fp;
    // 文件指针，文件不存在会创建，文件存在内容会清空
    fp = fopen("./1.txt", "w+");
    if (fp == NULL)
    {
        printf("打开文件失败!\n");
        return;
    }
    char str[100] = {"hello world"};
    printf("strlen(str)=%lu\n", strlen(str));
    for (size_t i = 0; i < strlen(str); i++)
    {
        // 循环将字符写入文件，这里执行完txt文件就可以看到内容了
        fputc(str[i], fp);
    }
    fseek(fp, 0, SEEK_SET); // 将文件指针移动到文件开头
    // rewind(fp);            /// 将文件指针移动到文件开头
    char ch[100] = {"\0"}; // 创建新变量用来存重文件读的数据
    int j;
    for (j = 0; !feof(fp); j++)
    {
        // 循环将文件内容读取赋值到ch中
        ch[j] = fgetc(fp);
    }
    ch[j-1] = '\0';
    printf("文件内读出来的内容:%s,长度为:%lu\n", ch, strlen(ch));
}
void file_fgets_fputs(void)
{
    FILE *fp=NULL;//文件指针
    fp=fopen("fgets_fputs.txt","w+");//r+：从文件首位置开始写入会覆盖前面的内容  w+  :刷新写入  a+:追加写入
    if(NULL==fp)
    {
        printf("文件打开失败\n");
        return ;
    }
    char str[100]={"8888\n"};
    fputs(str,fp);//写入一串字符
    fputs(str,fp);
    //将读写位置移动 移到文件首位置  
    rewind(fp);
    char buf[100]={'\0'};
    fgets(buf,sizeof(buf),fp);//从文件中读取sizeof(buf)-1个字符存入str  遇到换行停止读取
    printf("buf:%s\n",buf);
    fclose(fp);
}
//格式化读写操作
void file_fscanf_fprintf(void)
{
    struct file1
    {
       char name[20];
       int age;
       double score;
    }a={"zhangsan",19,98.7};//声明一个结构体类型并定义一个变量a并初始化赋值
    struct file1 b,c;//定义结构体类型变量
    FILE *fp=NULL;//文件指针
    fp=fopen("fscanf_fprintf.txt","w+");//打开文件
    if(NULL==fp)
    {
        return;
    }
    //a的信息输出到终端（屏幕）
    printf("%s %d %.2lf\n",a.name,a.age,a.score);
    //将a的信息  输出到文件
    fprintf(fp,"%s %d %.2lf\n",a.name,a.age,a.score);
    //通过键盘输入数据到b
    scanf("%s%d%lf",b.name,&b.age,&b.score);//输入的时候也要按照格式要求加入逗号 数据才会正确
    printf("b的信息：%s,%d,%.2lf\n",b.name,b.age,b.score);
    //从文件中通过fscanf函数将数据读取出来  存入变量c
    rewind(fp);//移到文件首位置
    fscanf(fp,"%s%d%lf",c.name,&c.age,&c.score);//遇到空格/回车/tab停止读取 
    printf("c的信息：%s,%d,%.2lf\n",c.name,c.age,c.score);
    fclose(fp);//关闭文件
}

//模块化读写
void file_fwrite_fread(void)
{
    struct file1
    {
       char name[20];
       int age;
       double score;
    }a={"zhangsan",19,98.7};//声明一个结构体类型并定义一个变量a并初始化赋值
    struct file1 b,c;//定义结构体类型变量
    FILE *fp=NULL;//文件指针
    fp=fopen("fwrite_fread.txt","w+");//打开文件
    if(NULL==fp)
    {
        return;
    }
    //将a的书通过fwrite写入文件
    fwrite(&a,sizeof(struct file1),1,fp);//参数（写入的数据地址，写入内容的大小，几块（内容大小），文件指针）
    //将数据从文件中通过fread读取出来
    rewind(fp);
    fread(&b,sizeof(struct file1),1,fp);
    printf("b的信息：%s,%d,%.2lf\n",b.name,b.age,b.score);
    fclose(fp);
    //2.写入结构体数组
    struct file1 num[2]={{"lisisan",39,78.7},{"wangwuliu",20,88.7}},arr[2];
    FILE *stu_fp=fopen("stu.txt","w+");
    if(!stu_fp)//等价于 fp==NULL
    {
        printf("文件打开失败\n");
        return;
    }
    //方法1  循环写入----
    // for(int i=0;i<2;i++)
    // {
    //     fwrite(&num[i],sizeof(struct file1),1,stu_fp);
    // }
    //=================================
    //方法2  一次性写入
    fwrite(num,sizeof(struct file1),2,stu_fp);
    //将文件读写位置移动
    rewind(stu_fp);
    //方法1：循环读出
    // for(int i=0;i<2;i++)
    // {
    //     fread(&arr[i],sizeof(struct file1),1,stu_fp);
    // }
     //=================================
    //方法2  一次性读出
    fread(arr,sizeof(struct file1),2,stu_fp);

    fclose(stu_fp);
    printf("输出读取的信息");
    //输出arr的信息
    for(int i=0;i<2;i++)
    {
        printf("%s,%d,%.2lf\n",arr[i].name,arr[i].age,arr[i].score);
    }


   
}
void main()
{
    FILE *fp;
    // 读，文件不存在会失败
    // file_r(fp);
    // 写，文件不存在会创建，文件存在会清空内容
    // file_w(fp);
    // 追加，文件不存在会创建，文件存在不会清空内容
    // file_a(fp);
    // 读写，文件不存在会失败，文件存在不会清空内容
    // file_r_add(fp);
    // 读写，文件存在会创建，文件存在会清空内容
    // file_w_add(fp);
    // 追加读写，文件不存在会创建，文件存在不会清空内容
    // file_a_add(fp);
    // file_position();
    // file_fgets_fputs();
    // file_fscanf_fprintf();
    file_fwrite_fread();
}